var App = Em.Application.create({
  cachedUserInfo : null,
  userInfo : function() {
    var me = this;
    if (!me.cachedUserInfo) {
      var jqxhr = $.getJSON('api/login/getUserInfo', function(userInfo) {
        console.log('ret userInfo loginURL='+userInfo.loginURL);
        me.set('cachedUserInfo',userInfo);
        if (userInfo.userId) { // logged in - should redirect
          App.router.transitionTo("main.trades.tradesList");
        }
      });
      jqxhr.error(function(jqXHR, textStatus, errorThrown) {
        console.debug("error " + textStatus);
        console.debug("incoming Text " + jqXHR.responseText);
      });
    }
    return me.cachedUserInfo;
  }.property('cachedUserInfo'),
  
  logout : function() { 
    if (this.cachedUserInfo.logoutURL) {
      location.href=this.cachedUserInfo.logoutURL; // this transits to the login URL
    }
  },
  
  login: function() {
    if (this.cachedUserInfo.loginURL) {
      location.href=App.cachedUserInfo.loginURL; // this transits to the login URL
    }
  },
  
  ready : function() {
    App.initialize();
  }
});

App.DAO = Em.Object.create({
  getJSON : function(url, func) {
    var jqxhr = $.getJSON(url, func);
    jqxhr.error(function(jqXHR, textStatus, errorThrown) {
      console.debug("error " + textStatus);
      console.debug("incoming Text " + jqXHR.responseText);
    });
  },
  ajax : function(obj) {
    var jqxhr = $.ajax(obj);
    jqxhr.error(function(jqXHR, textStatus, errorThrown) {
      console.debug("error " + textStatus);
      console.debug("incoming Text " + jqXHR.responseText);
    });
  },
  findAll: function (kind, content) {
    this.getJSON('api/'+kind+'/findAll', function(data) {
      $.each(data, function(index, value) {
        content.pushObject(value);
      });
    });
  },
  create : function (kind, entity, doneCallback) {
    this.ajax({
      url: 'api/'+kind+'/create',
      type: "POST",
      dataType: 'json',
      data: entity,
      success: function(returnedEntity) {
        doneCallback(returnedEntity);
      }
    });
  },
});

// create GridModel class
App.GridModel = Em.Object.extend({
  header : [],
  rows : [],
});

App.adminController = Em.Object.create({

  dataView : null,

  grid : null,

  gridTypeList : [ "Position", "Broker" ], // TODO: read from server

  gridType : null, // selected grid type

  uploadStatus : "Ready",

  initGrid : function() {
    var me = this;
    var url = "api/admin/getGridSetup/me.gridType";
    var jqxhr = $.getJSON(url, function(columns) {
      var gridOptions = {
        enableCellNavigation : true,
        enableColumnReorder : true,
        syncColumnCellResize : true,
        forceFitColumns : false,
        enableTextSelectionOnCells : false,
        topPanelHeight : 25,
        autoHeight : false,
        editable : true,
      };

      var data = [];

      me.dataView = new Slick.Data.DataView({
        inlineFilters : true
      });
      me.grid = new Slick.Grid("#myGrid", me.dataView, columns, gridOptions);
      me.grid.setSelectionModel(new Slick.RowSelectionModel());
      me.grid.onSelectedRowsChanged.subscribe(function() {
        console.debug(me.grid.getSelectedRows());
      });

      $('#myGrid').data('slickgrid', me.grid);
      me.dataView.setItems(data);
      me.grid.updateRowCount();
      me.grid.render();

      me.loadData(me.gridType);

      console.log("when sub: " + $("#middle-middle").height());

      window.onresize = function() {
        new_height = $("#middle-middle").height();
        console.log("changed to " + new_height);
        $("#myGrid").css('height', new_height);
        me.grid.resizeCanvas();
      };
    });

    jqxhr.error(function(jqXHR, textStatus, errorThrown) {
      console.debug("error " + textStatus);
      console.debug("incoming Text " + jqXHR.responseText);
    });
  },

  loadData : function() {
    var me = this;
    var url = "api/admin/getGridData/" + me.gridType;
    var jqxhr = $.getJSON(url, function(data) {
      me.dataView.setItems(data);
      me.grid.updateRowCount();
      me.grid.render();
    })
    jqxhr.error(App.adminController.ajaxError);
  },

  ajaxError : function(jqXHR, textStatus, errorThrown) {
    var me = this;
    console.debug("error " + textStatus);
    console.debug("incoming Text " + jqXHR.responseText);
    App.adminController.set('uploadStatus', 'Error');
  },

  clearData : function() {
    var me = this;
    me.set('gridModel', null);
  },

  uploadData : function() {
    var me = this;
    var formData = new FormData($('form')[0]);
    $.ajax({
      url : 'api/upload/upload', // server script to process data
      type : 'POST',
      xhr : function() { // custom xhr
        myXhr = $.ajaxSettings.xhr();
        if (myXhr.upload) { // check if upload property exists
          myXhr.upload.addEventListener('progress',
              App.adminController.progressHandlingFunction, false); // for
                                                                    // handling
                                                                    // the
                                                                    // progress
                                                                    // of the
                                                                    // upload
        }
        return myXhr;
      },
      // Ajax events
      beforeSend : function() {
      },
      success : function() {
        me.set('uploadStatus', 'Upload OK');
      },
      error : App.adminController.ajaxError,
      // Form data
      data : formData,
      // Options to tell JQuery not to process data or worry about content-type
      cache : false,
      contentType : false,
      processData : false
    });
  },

  progressHandlingFunction : function(e) {
    if (e.lengthComputable) {
      $('progress').attr({
        value : e.loaded,
        max : e.total
      });
    }
  },

});

App.Select = Em.Select.extend({});

App.UserView = Ember.View.extend({
      classNames : [ 'user-view' ],
      // template: Ember.Handlebars.compile("<a>user</a>")
      template : Ember.Handlebars
          .compile("<div class=\"btn-group\">"
              + "<a class=\"btn btn-inverse\" href=\"#\"><i class=\"icon-user icon-white\"></i> Avital Nahon</a>"
              + "<a class=\"btn btn-inverse dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\"><span class=\"caret\"></span></a>"
              + "<ul class=\"dropdown-menu\">"
              + "<li><a href=\"#\" {{action \"settings\" on=\"click\"}}><i></i>Settings</a></li>"
              + "<li><a href=\"#\" {{action \"logout\" on=\"click\"}}><i></i>Logout</a></li>"
              + "</ul>" + "</div>")
    });

App.NavItem = Ember.Object.extend({
  name : null,
  // A helper function to define a property used to render the navigation.
  // Returns
  // true if a state with the specified name is somewhere along the current
  // route.
  active : function() {
    var ret = "";
    var state = App.router.currentState;
    while (state) {
      if (state.name === this.name) {
        ret = "active";
        break;
      }
      state = state.get('parentState');
    }
    return ret;
  }.property('App.router.currentState'),
  isActive : function() {
    var state = App.router.currentState;
    while (state) {
      if (state.name === this.name) {
        return true;
      }
      state = state.get('parentState');
    }
    return false;
  }.property('App.router.currentState')
});

// function sectionRoute(name) {
// return Ember.Route.extend({
// route: name,
// connectOutlets: function(router, context) {
// var SectionView = Ember.View.extend({
// templateName: 'section' + name
// });
// router.get('sectionsController').connectOutlet({viewClass: SectionView});
// }
// });
// }

// Define the main application controller. This is automatically picked up by
// the application and initialized.





//---------- Application --------------

App.ApplicationController = Ember.Controller.extend({
});

App.ApplicationView = Ember.View.extend({
  templateName : 'application'
});

//---------- Application --------------

App.EntryController = Ember.Controller.extend();

App.EntryView = Ember.View.extend({
  templateName : 'entry'
});

//---------- Main --------------

App.MainController = Ember.Controller.extend({
  content : [ 
    App.NavItem.create({
      name : "trades",
      label : "Trades"
    }), 
    App.NavItem.create({
      name : "accounts",
      label : "Accounts"
    }), 
    App.NavItem.create({
      name : "history",
      label : "History"
    }), 
    App.NavItem.create({
      name : "cash",
      label : "Cash"
    }) 
  ],
});

App.MainView = Ember.View.extend({
  templateName : 'main'
});

//---------- Trades --------------

App.TradesController = Ember.Controller.extend({
});
App.TradesView = Ember.View.extend({
  templateName : 'trades'
});

App.TradesListController = Ember.Controller.extend({
  content: Ember.A([]),
  empty: function() {
    var b = this.content.length==0;
    return b;
  }.property('content.length'),
  loaded : null,
  load : function() {
    if (!this.loaded) {
      this.loaded = true;
      App.DAO.findAll("trade", this.content);
    }
  }
});
App.TradesListView = Ember.View.extend({
  templateName : 'tradesList'
});

App.NewTradeController = Ember.Controller.extend({

  model : { price : null, quantity : null, symbol : null, sdate : null, account: null, stageType: null },

  doCreate : function() {
    App.DAO.create("trade", this.model, this.onCreated);
  },
  
  onCreated : function(entity) {
    //console.log ("returning: " + JSON.stringify(returnedEntity));
    var tradesListController = App.get('router').get('tradesListController')
    var newTradeController = App.get('router').get('newTradeController')
    tradesListController.content.insertAt(0, entity);
    newTradeController.set('model',{ price : null, quantity : null, symbol : null, sdate : null, account: null, stageType: null }); 
  }
});

App.NewTradeView = Ember.View.extend({
  templateName : 'newTrade',
});


//---------- Accounts --------------

App.AccountsController = Ember.Controller.extend();
App.AccountsView = Ember.View.extend({
  templateName : 'accounts'
});

App.AccountsListController = Ember.Controller.extend({
  content: Ember.A([]),
  empty: function() {
    var b = this.content.length==0;
    return b;
  }.property('content.length'),
  loaded : null,
  load : function() {
    if (!this.loaded) {
      this.loaded = true;
      App.DAO.findAll("account", this.content);
    }
  }
});
App.AccountsListView = Ember.View.extend({
  templateName : 'accountsList',
});

App.ConnectAccountController = Ember.Controller.extend({

  model : { name : null, defaultTags : [] },

  doCreate : function() {
    App.DAO.create("account", this.model, this.onCreated);
  },
  
  onCreated : function(entity) {
    //console.log ("returning: " + JSON.stringify(returnedEntity));
    var accountsListController = App.get('router').get('accountsListController')
    var connectAccountController = App.get('router').get('connectAccountController')
    accountsListController.content.insertAt(0, entity);
    connectAccountController.set('model',{ name : null, defaultTags: null }); 
  }
});

App.ConnectAccountView = Ember.View.extend({
  templateName : 'connectAccount',
});


//---------- History --------------

App.HistoryController = Ember.Controller.extend();
App.HistoryView = Ember.View.extend({
  templateName : 'history'
});

//---------- Cash --------------

App.CashController = Ember.Controller.extend();
App.CashView = Ember.View.extend({
  templateName : 'cash'
});

App.Router = Ember.Router.extend({
  enableLogging : true,
  
  root : Ember.Route.extend({
    
    entry: Ember.Route.extend({
      route : '/',
      connectOutlets : function(router, event) {
        router.get('applicationController').connectOutlet('entry');
      },
      
      login : function() { App.login(); }
      
    }),
    
    main : Ember.Route.extend({

      connectOutlets : function(router, event) {
        router.get('applicationController').connectOutlet('main');
      },

      doItem : function(router, event) {
        var ctx = event.context;
        var name = ctx.name;
        if (name == "trades") {
          name = "trades.tradesList";
        } else if (name == "accounts") {
          name = "accounts.accountsList";
        }
        router.transitionTo(name);
      },
      
      logout: function(router, event) {
        App.logout();
      },
      
      index : Ember.Route.extend({
        route : '/',
        redirectsTo : 'trades.tradesList'
      }),

      trades : Ember.Route.extend({
        route : '/trades',
        connectOutlets : function(router, event) {
          router.get('mainController').connectOutlet('trades');
        },
        index : Ember.Route.extend({
          route : '/',
          redirectsTo : 'tradesList'
        }),
        tradesList : Ember.Route.extend({
          route : '/list',
          connectOutlets : function(router) {
            var controller = router.get('tradesController');
            controller.connectOutlet('tradesList');
          },
          enter: function(router) {
            router.get('tradesListController').load();
          },
          doNewTrade : Ember.Route.transitionTo('newTrade'),

        }),
        newTrade : Ember.Route.extend({
          route : '/new',
          connectOutlets : function(router) {
            var controller = router.get('tradesController');
            controller.connectOutlet('newTrade');
          },
          doCancel : Ember.Route.transitionTo('tradesList'),
          doCreate : function() {
            var controller = App.router.get('newTradeController');
            controller.doCreate();
            App.router.transitionTo('trades.tradesList');
          }
        })
      }),

      accounts : Ember.Route.extend({
        route : '/accounts',
        connectOutlets : function(router, event) {
          router.get('mainController').connectOutlet('accounts');
        },
        index : Ember.Route.extend({
          route : '/',
          redirectsTo : 'accountsList'
        }),
        accountsList : Ember.Route.extend({
          route : '/list',
          connectOutlets : function(router) {
            var controller = router.get('accountsController');
            controller.connectOutlet('accountsList');
          },
          enter: function(router) {
            router.get('accountsListController').load();
          },
          doConnectAccount : Ember.Route.transitionTo('connectAccount'),

        }),
        connectAccount : Ember.Route.extend({
          route : '/new',
          connectOutlets : function(router) {
            var controller = router.get('accountsController');
            controller.connectOutlet('connectAccount');
          },
          doCancel : Ember.Route.transitionTo('accountsList'),
          doCreate : function() {
            var controller = App.router.get('connectAccountController');
            controller.doCreate();
            App.router.transitionTo('accounts.accountsList');
          }
        })
      }),

      history : Ember.Route.extend({
        route : '/history',
        connectOutlets : function(router, event) {
          router.get('mainController').connectOutlet('history');
        },
      }),

      cash : Ember.Route.extend({
        route : '/cash',
        connectOutlets : function(router, event) {
          router.get('mainController').connectOutlet('cash');
        },
      })

    })

  }),
  
});

App.FieldView = Em.View
    .extend({
      classNames : [ 'control-group' ],
      tagName : 'div',
      type : 'text',
      label : null,
      value : null,
      size : '30',
      required : null,
      requiredAttribute : (function() {
        if (this.get('required') === 'true') {
          return '';
        } else {
          return null;
        }
      }).property('required'),
      // childViews : 'labelView dataView'.w(),
      labelView : Em.View.extend({
        tagName : 'label',
        classNames : [ 'control-label' ],
        attributeBindings : [ 'for' ],
        forBinding : 'parentView.dataView.elementId',
        textBinding : 'parentView.label',
        requiredBinding : 'parentView.required',
        defaultTemplate : Em.Handlebars.compile('{{view.text}}')
      }),
      dataView : Em.TextField.extend({
        attributeBindings : 'type value size placeholder required'.w(),
        typeBinding : 'parentView.type',
        sizeBinding : 'parentView.size',
        valueBinding : 'parentView.value',
        requiredBinding : 'parentView.requiredAttribute'
      }),
      defaultTemplate : Ember.Handlebars
          .compile('{{view view.labelView}}<div class=\"controls\">{{view view.dataView}}{{#if view.required}} <i class=\"icon-hand-left\"></i>   {{/if}}</div>')
    });


App.TextField = App.FieldView.extend();

App.TextArea = App.FieldView.extend({
  dataView : Em.TextArea.extend()
});

App.EmailField = App.FieldView.extend({
  type : 'email'
});

App.PasswordField = App.FieldView.extend({
  type : 'password'
});

App.DateField = App.FieldView.extend({
  dataView : Em.TextField.extend({
    attributeBindings : 'type value size placeholder required'.w(),
    typeBinding : 'parentView.type',
    sizeBinding : 'parentView.size',
    valueBinding : 'parentView.value',
    requiredBinding : 'parentView.requiredAttribute',
    didInsertElement : function() {
      this.$().datepicker();
    }
  })
});

App.NumberTextField = Ember.TextField.extend({
  keyPress : function(event) {
    var charCode = event.which; // charCode will contain the code of the
                                // character inputted
    // console.log(charCode);
    // Allow: backspace, delete, tab, escape, and enter and dot
    if (charCode == 46 || charCode == 8 || charCode == 9 || charCode == 27
        || charCode == 13 ||
        // Allow: Ctrl+A
        (charCode == 65 && event.ctrlKey === true) ||
        // Allow: home, end, left, right
        (charCode >= 35 && charCode <= 39)) {
      // let it happen, don't do anything
    } else {
      if (event.shiftKey || (charCode < 48 || charCode > 57)) {
        event.preventDefault();
      }
      // var theChar = String.fromCharCode(charCode);
    }
  }
});

App.NumberField = App.FieldView.extend({
  dataView : App.NumberTextField
      .extend({
        type : 'number',
        attributeBindings : 'type value size placeholder min max step required'
            .w(),
        minBinding : 'parentView.min',
        maxBinding : 'parentView.max',
        sizeBinding : 'parentView.size',
        valueBinding : 'parentView.value',
        requiredBinding : 'parentView.requiredAttribute'
      })
});

App.TypeaheadField = App.FieldView.extend({
  dataView : Em.TextField.extend({
    classNames : ['typeahead'],
    attributeBindings : 'type value size placeholder required'.w(),
    typeBinding : 'parentView.type',
    sizeBinding : 'parentView.size',
    valueBinding : 'parentView.value',
    requiredBinding : 'parentView.requiredAttribute',
    urlBinding: 'parentView.url',
    propertyBinding : 'parentView.property',
    propertiesBinding: 'parentView.properties',
    didInsertElement : function() {
      var me = this;
      this.$().typeahead({
        strings : false,
        property : me.property,
        properties: me.properties,
        source : function (typeahead, query) {
          App.DAO.getJSON('api/'+me.url, function(data) {
            typeahead.process(data);
          });
        },
        menu: '<table class="table table-condensed typeahead dropdown-menu" style="width:400px">'+
//        '<thead><tr class="tableheader">'+
//        '<th>Symbol</th>'+
//        '<th>Instrument</th>'+
//        '<th>Currency</th>'+
//        '</tr></thead>'+
        '<tbody></tbody></table>',
        item: '<tr> <td><a id="0"></a></td> <td><a id="1"></a></td> <td><a id="2"></a></td> </tr>',
        items : 10
      });
    }
  })
});

App.TypeaheadField.reopen({
  valueChanged: function() {
    console.log("typeahead value changed to /" + this.get('value') + "/");
  }.observes('value')
});

App.SymbolField = App.TypeaheadField.extend({
  property : 'id',
  properties: ['id','instrument', 'currency'],
  url: 'symbol/pickerFindAll'
});

App.AccountField = App.TypeaheadField.extend({
  property : 'id',
  properties: ['name'],
  url: 'account/pickerFindAll'
});

App.StageTypeField = App.TypeaheadField.extend({
  property : 'id',
  properties: ['id'],
  url: 'trade/stageTypePicker'
});

App.TagsFormField = App.FieldView.extend({
  dataView : Em.TagsField.extend()
});




